package com.spark.core;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletConfig;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.spark.tags.Component;
import com.spark.util.MemcachedHelper;

import freemarker.ext.beans.BeansWrapper;
import freemarker.template.Configuration;
import freemarker.template.TemplateHashModel;
import freemarker.template.TemplateModelException;

public class SparkContext {
	
	public static final String SPARK_USER_KEY = "SUK";
	public static final String SPARK_WINDOW_ID = "WID";
	
	public static final String SPARK_REQUEST = "request";
	public static final String SPARK_SESSION = "session";
	public static final String CONTEXT_PATH = "context_path";
//	public static final String USER_AGENT = "__user_agent";
	public static final String REQUEST_DATA = "_request_data";
	public static final String PARAMETER = "parameter";
	
	public static final String FIELD_USER_ID = "USER_ID";
	public static final String FIELD_COMPANY_CODE = "COMPANY_CODE";
	public static final String FIELD_COMPANY_ID = "COMPANY_ID";
	public static final String FIELD_COMPANY_NAME = "COMPANY_NAME";
	public static final String FIELD_USER_NAME = "USER_NAME";
	public static final String FIELD_EMPLOYEE_NAME = "EMPLOYEE_NAME";
	public static final String FIELD_ACCOUNT_SET_ID = "ACCOUNT_SET_ID";
	
	private SparkConfiguration sparkConfiguration;
	private List<String> styleSheetList = new ArrayList<String>();
	private List<String> javascriptList = new ArrayList<String>();
	private List<String> idList = null;
	private ServletConfig servletConfig;
	private XMap parameter = new XMap();
	private HttpServletRequest request;
	private HttpServletResponse response;
	private Map<String, Object> jsonConfig = new HashMap<String, Object>(100);
	private Map<String, Object> map = new HashMap<String, Object>(100);//生命周期是在一个标签内执行的上下文
	private Map<String, Object> model = new HashMap<String,Object>(50);//声明周期是在screen的整个上下文
	private String contextPath = "";
	private String userAgent = "";
	private Map<String,XMap> dataSets = new HashMap<String,XMap>();
	private Map<String, Object> session = new HashMap<String, Object>(50);
	private SparkTemplate template;
	
	
	
	public SparkContext createInstance(){
		SparkContext instance = new SparkContext(sparkConfiguration);
		instance.servletConfig = servletConfig;
		instance.setRequest(request);
		instance.setResponse(response);
		instance.setContextPath(contextPath);
		instance.setUserAgent(userAgent);
		instance.setParameter(parameter);
		instance.styleSheetList = styleSheetList;
		instance.javascriptList = javascriptList;
		instance.idList = idList;
		instance.dataSets = dataSets;
		instance.model = model;
		instance.session = session;
		instance.template = template;		
		return instance;
	}
	
	public List<String> getIdList(){
		return idList;
	}
	
	public void openIdTrace(){
		this.idList = new ArrayList<String>();
	}
	public void closeIdTrace(){
		this.idList = null;
	}
	
	public void putDataSet(XMap ds){
		String id = ds.getString(Component.PROPERTITY_ID);
		dataSets.put(id, ds);
	}
	
	public XMap getDataSet(String id){
		return dataSets.get(id);
	}
	
	public String getUserAgent() {
		return userAgent;
	}

	public void setUserAgent(String agent) {
		this.userAgent = agent;
	}
	
	public String getContextPath() {
		return contextPath;
	}

	public void setContextPath(String contextPath) {
		this.contextPath = contextPath;
		this.put(SparkContext.CONTEXT_PATH, contextPath);
	}
	
	@SuppressWarnings("unchecked")
	public Map getModel(){
		return model;
	}

	public void put(String key, Object value){
		map.put(key, value);
	}
	
	public Object get(String key){
		return map.get(key);
	}
	
	public Map<String, Object> getMap(){
		return map;
	}
	
	public void initSession(){
		HttpServletRequest request = this.getRequest();
		String suk = request.getParameter(SparkContext.SPARK_USER_KEY);
		if(suk!=null && !"".equals(suk.trim())){
			String ukey = (String)MemcachedHelper.get(suk);
			if(ukey!=null){
				String[] arr = ukey.split("#");
				if(arr.length == 4){
					Map<String,Object> session = this.getSession();
					session.put(FIELD_USER_ID, Integer.valueOf(arr[0]));
					session.put(FIELD_COMPANY_ID, Integer.valueOf(arr[1]));
					session.put(FIELD_COMPANY_NAME, arr[2]);
					session.put(FIELD_EMPLOYEE_NAME, arr[3]);
					//TODO:科目表ID应该从当前帐套中获取
					session.put(FIELD_ACCOUNT_SET_ID, 1);
				}
			}
			
		}
	}
	
	public Map<String, Object> getSession(){
		return session;
	}
	
	@SuppressWarnings("unchecked")
	public Map getFreeMarkerModel() throws TemplateModelException{
		Map map = this.getMap();
		map.putAll(this.getModel());
		map.put(SPARK_SESSION, this.getSession());
		
		BeansWrapper wrapper = BeansWrapper.getDefaultInstance();
		TemplateHashModel staticModels = wrapper.getStaticModels();
		TemplateHashModel JacksonMapper = (TemplateHashModel) staticModels.get("com.spark.core.JacksonMapper");
		map.put("JacksonMapper", JacksonMapper);
		return map;
	}
	
	public String getJsonConfig() throws Exception {
		return JacksonMapper.getInstance().writeValueAsString(jsonConfig);
	}
	
	public void removeJsonConfig(String key){
		jsonConfig.remove(key);
	}

	public void addJsonConfig(String key, Object value) {
		jsonConfig.put(key, value);
	}
	
	public void setServletConfig(ServletConfig config) {
		this.servletConfig = config;
	}
	
	public ServletConfig getServletConfig(){
		return this.servletConfig;
	}
	
	public XMap getParameter() {
		return parameter;
	}

	public void setParameter(XMap parameter) {
		put(SparkContext.SPARK_REQUEST, parameter);
		this.parameter = parameter;
	}

	public HttpServletRequest getRequest() {
		return request;
	}

	public void setRequest(HttpServletRequest request) {
		put("request", request);
		this.request = request;
	}

	public HttpServletResponse getResponse() {
		return response;
	}

	public void setResponse(HttpServletResponse response) {
		this.response = response;
	}

	public SparkContext(SparkConfiguration configuration) {
		setSparkConfiguration(configuration);
	}


	// public XMap getParameter() {
	// return parameter;
	// }
	//
	// public void setParameter(XMap parameter) {
	// this.parameter = parameter;
	// }

	public SparkConfiguration getSparkConfiguration() {
		return sparkConfiguration;
	}

	public void setSparkConfiguration(SparkConfiguration configuration) {
		this.sparkConfiguration = configuration;
	}
	
	public List<String> getStyleSheet(){
		return styleSheetList;
	}
	
	public List<String> getJavaScript(){
		return javascriptList;
	}

	public void addStyleSheet(String styleSheet) {
		if (styleSheetList.indexOf(styleSheet) == -1)
			styleSheetList.add(styleSheet);
	}

	public void addJavaScript(String javascript) {
		if (javascriptList.indexOf(javascript) == -1)
			javascriptList.add(javascript);
	}

	public Configuration getFreemarkerConfiguration() {
		return getSparkConfiguration().getFreemarkerConfiguration();
	}

	public SparkTemplate getTemplate() {
		return template;
	}

	public void setTemplate(SparkTemplate template) {
		this.template = template;
	}
	
	
	@SuppressWarnings("unchecked")
	public Map getRequestData(){
		XMap params = this.getParameter();
		Map data = new HashMap(100);
		if(params!=null){
			Map rd = (Map)params.get(REQUEST_DATA);
			if(rd!=null){
				data = rd;
			}
		}
		return data;
	}
	
	@SuppressWarnings("unchecked")
	public Map getParameterMap(){
		Map data = this.getRequestData();
		Map parameter = (Map)data.get(PARAMETER);
		Map para = new HashMap(100);
		
		para.putAll(this.getSession());
		para.putAll(parameter);
		
		return para;
	}
	
	@SuppressWarnings("unchecked")
	protected List getParameterList(){
		Map data = getRequestData();
		List list = (List)data.get(PARAMETER);
		return list == null ? new ArrayList() : list;
	}

}
